package com.idanchuang.component.provider;

import com.idanchuang.component.provider.api.util.RpcThreadLocalUtil;
import com.idanchuang.component.provider.config.RpcConfig;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yjy
 * @date 2020/5/22 17:10
 **/
public class RpcContext {

    /**
     * 存入一个值
     *
     * @param key   名
     * @param value 值
     */
    public static void addToThreadLocal(String key, String value) {
        RpcThreadLocalUtil.addToThreadLocal(key, value);
    }

    /**
     * 存入一个值的集合
     *
     * @param datas 值集合
     */
    public static void addToThreadLocal(Map<String, String> datas) {
        RpcThreadLocalUtil.addToThreadLocal(datas);
    }

    /**
     * 从变量表中取出一个值
     *
     * @param key 名
     * @return 值
     */
    public static String getFromThreadLocal(String key) {
        return RpcThreadLocalUtil.getFromThreadLocal(key);
    }

    /**
     * 从变量表中取出一个值, 不存在时返回默认值
     *
     * @param key          名
     * @param defaultValue 默认值
     * @return 值或默认值
     */
    public static String getFromThreadLocal(String key, String defaultValue) {
        return RpcThreadLocalUtil.getFromThreadLocal(key, defaultValue);
    }

    /**
     * 从变量表中移除一个值
     *
     * @param key 名
     * @return 被移除的值
     */
    public static String removeFromThreadLocal(String key) {
        return RpcThreadLocalUtil.removeFromThreadLocal(key);
    }

    /**
     * 清空变量表
     */
    public static void clearThreadLocal() {
        RpcThreadLocalUtil.clearThreadLocal();
    }

    /**
     * 获取整个变量表
     *
     * @return 值集合
     */
    public static Map<String, String> getAllFromThreadLocal() {
        return RpcThreadLocalUtil.getAllFromThreadLocal();
    }

    /**
     * 获取RPC调用方信息
     *
     * @return 来源信息
     */
    public static String getRpcFrom() {
        String rpcFromName = RpcConfig.getInstance().getRpcFromName();
        String from = getRpcHeader(rpcFromName);
        if (from != null) {
            return from;
        }
        return getRpcParameter(rpcFromName);
    }

    /**
     * 获取RPC调用参数
     *
     * @return 来源信息
     */
    public static String getRpcParameter(String name) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            return req.getParameter(name);
        }
        return null;
    }

    /**
     * 获取RPC调用参数
     *
     * @return 来源信息
     */
    public static Map<String, String[]> getRpcParameters() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            return req.getParameterMap();
        }
        return new HashMap<>();
    }

    /**
     * 获取RPC调用header
     *
     * @return header
     */
    public static String getRpcHeader(String name) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            return req.getHeader(name);
        }
        return null;
    }

    /**
     * 获取RPC调用headers
     *
     * @return headers
     */
    public static Map<String, Enumeration<String>> getRpcHeaders() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Map<String, Enumeration<String>> headers = new HashMap<>();
            String headerName;
            Enumeration<String> headerNames = req.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                headerName = headerNames.nextElement();
                headers.put(headerName, req.getHeaders(headerName));
            }
            return headers;
        }
        return new HashMap<>();
    }

}
